package com.yanqu.road.server.manager.strongholdwar;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.stronghold.*;
import com.yanqu.road.entity.activity.stronghold.config.StrongholdEliminateReportDetail;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.pb.activity.StrongholdWarProto;
import com.yanqu.road.pb.rank.UnionActivityRankProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameErrorCode;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossStrongholdMgr extends TempCrossMgr {

    private static Map<Integer, StrongholdActivityModelGroup> activityModelGroupMap = new ConcurrentHashMap<>();


    public static List<StrongholdWarProto.StrongholdFightStatusTempMsg.Builder> getWildListData(int activityId, int groupId) {
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        if (model == null) {
            return new ArrayList<>();
        }
        return model.getWildListData();
    }

    public static StrongholdActivityModel getActivityModel(int activityId, int groupId) {
        StrongholdActivityModelGroup modelGroup = activityModelGroupMap.get(activityId);
        if (null == modelGroup) {
            synchronized (activityModelGroupMap) {
                modelGroup = activityModelGroupMap.get(activityId);
                if (null == modelGroup) {
                    ActivityInfo activityInfo = CrossStrongholdActivityMgr.getOpenActivityInfo(activityId);
                    if (null == activityInfo){
                        CrossStrongholdActivityMgr.reloadActivityInfo(activityId);
                    }
                    modelGroup = new StrongholdActivityModelGroup(activityId);
                    activityModelGroupMap.put(activityId, modelGroup);
                }
            }
        }

        StrongholdActivityModel model = modelGroup.getActivityModel(groupId);

        return model;
    }

    public static int move(int activityId, int nextWildId, long serverId, long userId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.move(nextWildId, serverId, userId);
    }

    public static int dispatchPatrons(int activityId, int wildId, long serverId, long playerId, UserBaseInfo userBaseInfo, UserPatrons patrons) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, playerId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.dispatchPatrons(wildId, serverId, playerId, userBaseInfo, patrons);
    }

    public static void loadActivity(int activityId) {
        if (activityModelGroupMap == null) {
            activityModelGroupMap = new ConcurrentHashMap<>();
        }

        Map<Integer, UnionActivityGroup> groupMap = Cross2UnionActivityGroupMgr.getGroupMap(activityId);
        if (null != groupMap) {
            for (UnionActivityGroup activityGroup : groupMap.values()) {
                if (activityGroup.getCrossServerId() == CrossBaseServer.getInstance().getServerId()) {
                    getActivityModel(activityId, activityGroup.getGroupId());
                }
            }
        }
    }

    public static StrongholdWarProto.CrossStrongholdSearchRespMsg.Builder search(int activityId, long serverId, long userId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.search(serverId, userId);
    }

    public static StrongholdWildUserData getWildUser(int activityId, long serverId, long userId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        if (model == null) {
            return null;
        }
        StrongholdWildUserData patrons = model.getPatrons(serverId, userId);
        return patrons;
    }

    public static StrongholdWarProto.StrongholdDataResp.Builder getSingleWildMsg(int activityId, long serverId, long userId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        StrongholdWildUserData userData = activityModel.getPatrons(serverId, userId);
        return activityModel.getWildData(userData);
    }

    public static StrongholdWarProto.CrossDealStrongholdEventResp.Builder dealEvent(int activityId, long serverId, long userId, boolean isDeal) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        return model.dealEvent(serverId, userId, isDeal);
    }

    public static StrongholdOpenBoxResult openBox(int activityId, long serverId, long userId, int boxId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        if (model == null) {
            return new StrongholdOpenBoxResult(GameErrorCode.E_STRONGHOLD_NOT_FOUND);
        }
        return model.openBox(serverId, userId, boxId);
    }

    public static CrossStrongholdEliminateUnion chooseChallengeUnion(int activityId, int groupId, int id) {
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.chooseChallengeUnion(id);
    }

    public static void uploadBase(int activityId, int groupId, long serverId, List<CrossStrongholdEliminateUnion> eliminateUnions) {
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        activityModel.uploadUnionBase(serverId, eliminateUnions);
    }

    public static void updateUnionBase(int activityId, String unionId, UnionBaseInfo unionBaseInfo) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        activityModel.updateUnionBase(unionId, unionBaseInfo);
    }

    public static List<CrossStrongholdEliminateUnion> getEliminateUnionList(int activityId, int groupId) {
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.getEliminateUnionList();
    }

    public static AttackUnionResult attackUnion(int activityId, long userId, UserBaseInfo userBaseInfo, int patronsId, BigInteger damage, int id) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        return model.attack(userId, userBaseInfo, patronsId, damage, id);
    }

    public static Map<String, StrongholdEliminateReport> getEliminateReport(int activityId, int groupId, int id, int type) {
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.getEliminateReport(id, type);
    }

    public static List<StrongholdEliminateReportDetail> getEliminateReportDetail(int activityId, int groupId, int id, int type, int id2) {
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.getEliminateReportDetail(id, type, id2);
    }


    public static MammonHelpResult mammonHelp(int activityId, long userId, UserBaseInfo userBaseInfo, List<Integer> idList, int type, int mammonType, BigInteger totalDamage, int attackTimes) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
        StrongholdActivityModel activityModel = getActivityModel(activityId, groupId);
        return activityModel.mammonHelp(userId, userBaseInfo, type, mammonType, idList, totalDamage, attackTimes);
    }



    public static Map<Integer, List<CrossStrongholdUserRoungDamage>> getUserDamageMap(int activityId, String unionId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        if (model == null) {
            return new HashMap<>();
        }
        return model.getUnionMemberDamageMap(unionId);
    }

    public static BigDecimal getUnionScore(int activityId, String unionId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        if (model == null) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(model.getUnionScore(unionId));
    }

    public static void resetUnionScore() {
        for (StrongholdActivityModelGroup modelGroup : activityModelGroupMap.values()) {
            for (StrongholdActivityModel model : modelGroup.getActivityModelList()) {
                model.checkAndResetUnionScore();
            }
        }
    }

    public static List<CrossStrongholdEliminateDefendPatrons> getEliminateDefendPatrons(int activityId, String unionId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionId);
        StrongholdActivityModel model = getActivityModel(activityId, groupId);
        CrossStrongholdEliminateModel eliminateModel = model.getCrossStrongholdEliminateModel();
        return eliminateModel.getDefendPatronsByUnionId(unionId);
    }


    @Override
    public boolean reloadData() throws Exception {
        for (ActivityInfo activityInfo : CrossStrongholdActivityMgr.getOpenActivityInfoMap().values()) {
            loadActivity(activityInfo.getActivityId());
        }
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean save() {
        for (StrongholdActivityModelGroup modelGroup : activityModelGroupMap.values()) {
            for (StrongholdActivityModel model : modelGroup.getActivityModelList()) {
                model.save();
            }
        }
        return true;
    }

    public static void refreshBox() {
        for (StrongholdActivityModelGroup modelGroup : activityModelGroupMap.values()) {
            for (StrongholdActivityModel model : modelGroup.getActivityModelList()) {
                model.checkAndRefreshBox();
            }
        }
    }

    public static Set<String> getQualifyUnionList(int activityId, int groupId) {
        Set<String> qualifyList = new HashSet<>();
        if (CrossStrongholdActivityMgr.isLookWildRank(activityId)) {
            //野外据点前几名
            int rankNum = CrossStrongholdActivityMgr.getQualifyNum(activityId);
            UnionActivityRankProto.UnionActivityRankListMsg rankList = CrossStrongholdRankMgr.getCrossActivityUnionRankListModel(activityId, groupId, CrossStrongholdActivityMgr.CONDITION_TYPE_WILD_UNION, true).getRankListMsg().build();
            if (rankList != null) {
                qualifyList.addAll(findServerQualifyUnion(rankNum, rankList));
            }
        } else {
            // 淘汰赛前几名
            int rankNum = CrossStrongholdActivityMgr.getQualifyNum(activityId);
            UnionActivityRankProto.UnionActivityRankListMsg rankList = CrossStrongholdRankMgr.getCrossActivityUnionRankListModel(activityId, groupId, CrossStrongholdActivityMgr.CONDITION_TYPE_ELIMINATE_UNION, true).getRankListMsg().build();

            if (rankList != null) {
                qualifyList.addAll(findServerQualifyUnion(rankNum, rankList));
            }
        }
        return qualifyList;
    }

    public static int getSilverRank(int activityId, String unionUid) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionUid);
        Collection<String> allQualifyUnion = getQualifyUnionList(activityId, groupId);
        if (!allQualifyUnion.contains(unionUid)) {
            return 0;
        }

        int myRank = -1;
        UnionActivityRankProto.UnionActivityRankListMsg rankList = CrossStrongholdRankMgr.getCrossActivityUnionRankListModel(activityId, groupId, eGamePlayerEventType.StrongholdDonateSilverRank.getValue(), true).getRankListMsg().build();
        if (rankList == null) {
            return myRank;
        }
        int rank = 0;
        for (UnionActivityRankProto.UnionActivityRankTempMsg msg : rankList.getRankListList()) {
            String uid = msg.getUnionUid();
            if (allQualifyUnion.contains(uid)) {
                rank++;
                if (msg.getUnionUid().equals(unionUid)) {
                    myRank = rank;
                    break;
                }
            }
        }
        return myRank;
    }

    private static Collection<? extends String> findServerQualifyUnion(int rankNum, UnionActivityRankProto.UnionActivityRankListMsg rankList) {
        int rank = 0;
        List<String> unionUidList = new ArrayList<>();
        for (UnionActivityRankProto.UnionActivityRankTempMsg msg : rankList.getRankListList()) {
            rank++;
            String unionUid = msg.getUnionUid();
            unionUidList.add(unionUid);
            if (rank >= rankNum) {
                break;
            }
        }
        return unionUidList;
    }

    public boolean removeExpireData() {
        List<Integer> acList = new ArrayList<>();
        long nowTime = System.currentTimeMillis();
        for (Integer activityId : activityModelGroupMap.keySet()) {
            ActivityInfo activityInfo = CrossStrongholdActivityMgr.getOpenActivityInfo(activityId);
            if (activityInfo == null || (nowTime > activityInfo.getEndShowTime() * 1000 + 3 * 24 * 3600 * 1000)) {
                acList.add(activityId);
            }
        }
        for (Integer activityId : acList) {
            activityModelGroupMap.remove(activityId);
        }
        return true;
    }

}
